--- import Layout from '../../layouts/Layout.astro'; import ProductCard from '../../components/ProductCard.astro'; import PriceComparisonTable from '../../components/PriceComparisonTable.tsx'; import PriceHistoryChart from '../../components/PriceHistoryChart.tsx'; import { getProductBySlug, getProductsFromDB, getBrandBySlugFromDB } from '../../lib/products'; function getDiscountPercent(sneaker: { originalPrice: number; lowestPrice: number }): number { return Math.round(((sneaker.originalPrice - sneaker.lowestPrice) / sneaker.originalPrice) * 100); } const { slug } = Astro.params; const sneaker = await getProductBySlug(slug!); if (!sneaker) return Astro.redirect('/sneakers'); const discount = getDiscountPercent(sneaker); const related = await getProductsFromDB({ limit: 4, brand: sneaker.brandSlug }); const brandInfo = await getBrandBySlugFromDB(sneaker.brandSlug); const viewItemData = { item_id: sneaker.id, item_name: `${sneaker.brand} ${sneaker.name}`, item_brand: sneaker.brand, price: sneaker.lowestPrice, item_category: sneaker.name, }; const schema = { "@context": "https://schema.org", "@type": "Product", name: `${sneaker.brand} ${sneaker.name}`, description: `${sneaker.brand} ${sneaker.name} - ${sneaker.colorway}`, brand: { "@type": "Brand", name: sneaker.brand }, offers: { "@type": "AggregateOffer", lowPrice: sneaker.lowestPrice, highPrice: Math.max(...sneaker.offers.map(o => o.price)), priceCurrency: "EUR", offerCount: sneaker.offers.length, }, }; --- Home / Sneakers / {sneaker.brand} / {sneaker.name} {discount > 0 && ( -{discount}% )} {brandInfo?.logo_url && ( )} {sneaker.brand} {sneaker.name} {sneaker.colorway} €{sneaker.lowestPrice.toFixed(2).replace('.', ',')} {sneaker.originalPrice > sneaker.lowestPrice && ( €{sneaker.originalPrice.toFixed(2).replace('.', ',')} )} Laagste prijs bij {sneaker.offers.sort((a, b) => a.price - b.price)[0].shop} {sneaker.gender === 'heren' ? '👨 Heren' : sneaker.gender === 'dames' ? '👩 Dames' : '🧑 Unisex'} 📅 {new Date(sneaker.releaseDate).toLocaleDateString('nl-NL', { day: 'numeric', month: 'long', year: 'numeric' })} {sneaker.offers.filter(o => o.inStock).length} shops op voorraad Prijsalert instellen Beschikbare maten {sneaker.sizes.map(size => { const available = sneaker.offers.some(o => o.inStock && o.sizes.includes(size)); return ( EU {size} ); })} {related.length > 0 && ( Meer van {sneaker.brand} {related.map((s, i) => ( ))} )}
{sneaker.brand}
{sneaker.colorway}